<template>
  <basic-modal
    v-bind="$attrs"
    show-confirm
    @confirm="confirm"
    :confirm-loading="confirmLoading"
  >
    <n-spin :show="confirmLoading">
      <div class="flex justify-between mb-4 text-base">
        <span>{{ paymentTitle }}：</span>
        <span>{{ currencyFormat(totalPrice) }}</span>
      </div>
      <div class="">
        <n-form :model="paymentForm" ref="formRef">
          <n-space vertical>
            <div
              class="payment-item"
              :class="{ 'payment-item--active': item.checked }"
              v-for="item in paymentForm.paymentList"
              :key="item.value"
            >
              <n-grid
                :cols="24"
                :x-gap="10"
                :y-gap="10"
                class="flex items-center"
              >
                <n-gi :span="12">
                  <div>
                    <n-checkbox
                      :checked="item.checked"
                      @click.stop="handleClickPaymentItem(item)"
                      class="flex items-center py-1"
                    >
                      <div class="flex items-center">
                        <img
                          class="w-[28px]"
                          :src="getPaymentAsset(`${item.value}.png`)"
                        />
                        <span
                          style="font-weight: 600; font-size: 16px"
                          class="ml-1"
                        >
                          {{ item.label }}
                        </span>
                      </div>
                    </n-checkbox>
                  </div>
                </n-gi>
                <n-gi :span="12">
                  <div class="text-right" v-show="item.checked">
                    <n-input-number v-model:value="item.amount">
                      <template #prefix> {{ prefix }} </template>
                    </n-input-number>
                  </div>
                </n-gi>
              </n-grid>
            </div>
          </n-space>
        </n-form>
      </div>
    </n-spin>
  </basic-modal>
</template>
<script setup lang="ts">
import { ref, useAttrs, watch } from "vue";
import { FormInst, useMessage } from "naive-ui";
import { isEmpty, debounce } from "lodash-es";
import { v4 as uuidv4 } from "uuid";
import Big from "big.js";
import { MONET_PREFIX } from "@/constants/global";
import { getPaymentAsset } from "@/common/utils/payment/index";
import { currencyFormat } from "@/common/utils/currencyFormatter/index.ts";
import { IPaymentModalProps } from "./props";

const $emits = defineEmits(["confirm"]);

const $attrs = useAttrs();
const message = useMessage();

const props = withDefaults(defineProps<IPaymentModalProps>(), {
  paymentTitle: "支付金额",
  totalPrice: 0,
  prefix: MONET_PREFIX,
  paymentMethods: () => [],
  confirmLoading: false,
  checkEquels: true,
});

const paymentForm = ref({
  paymentList: [] as any[],
});

const formRef = ref<FormInst | null>(null);

watch(
  [() => $attrs.show, () => props.paymentMethods],
  ([show, paymentMethods]) => {
    if (show && !isEmpty(paymentMethods)) {
      paymentForm.value.paymentList = paymentMethods.map((item) => {
        return {
          ...item,
          uuid: uuidv4(),
          checked: false,
          amount: 0,
        };
      });
    }
  }
);

const handleClickPaymentItem = (paymentItem: any) => {
  if (paymentItem.checked) {
    paymentItem.amount = 0;
    paymentItem.checked = false;
  } else {
    const hasChecked = paymentForm.value.paymentList.some(
      (item) => item.checked
    );
    if (!hasChecked) {
      // 没有选中任何支付方式
      paymentItem.checked = !paymentItem.checked;
      paymentItem.amount = new Big(props.totalPrice);
    } else {
      // 已经有选中支付方式
      let selectedTotal = new Big(0);
      paymentForm.value.paymentList.forEach((item) => {
        if (item.checked) {
          selectedTotal = selectedTotal.plus(item.amount);
        }
      });

      if (selectedTotal.lt(props.totalPrice)) {
        paymentItem.checked = true;
        paymentItem.amount = new Big(props.totalPrice)
          .minus(selectedTotal)
          .valueOf();
        paymentItem.checked = true;
      }
    }
  }
};

const confirm = debounce(function () {
  const hasChecked = paymentForm.value.paymentList.some((item) => item.checked);

  if (!hasChecked) {
    message.error("请选择支付方式");
    return;
  }

  const checkedPaymentList = paymentForm.value.paymentList.filter(
    (item) => item.checked
  );

  if (!props.checkEquels) {
    $emits(
      "confirm",
      checkedPaymentList.map((item) => {
        return {
          amount: item.amount.toString(),
          paymentMethod: item.value,
        };
      })
    );
    return;
  }

  let _amountTotal = new Big(props.totalPrice);
  let _computedTotal = new Big(0);

  checkedPaymentList.forEach((item) => {
    _computedTotal = _computedTotal.plus(item.amount);
  });

  if (_computedTotal.eq(_amountTotal)) {
    $emits(
      "confirm",
      checkedPaymentList.map((item) => {
        return {
          amount: item.amount.toString(),
          paymentMethod: item.value,
        };
      })
    );
  } else {
    message.error("金额不对等");
  }
}, 200);
</script>
<style lang="scss" scoped>
.payment-item {
  @apply w-full border border-transparent rounded-lg  p-3 relative flex flex-col items-center justify-center text-ellipsis overflow-hidden bg-slate-100 cursor-pointer hover:border-theme-main-color;

  &--active {
    @apply border-theme-main-color;
  }
}
</style>
